package com.example.mqtt.common;

import lombok.extern.slf4j.Slf4j;

/**
 * @author zhangtai
 * CRC 检查
 */
@Slf4j
public class CRCnew {

    static int poly = 0x1021;
    private static int calc_crc(int crc,  int ch) {

        int i;
        ch <<= 8;
        for (i = 8; i > 0; i--) {
            if (((ch^crc) & 0x8000)!=0) {
                crc = (crc << 1) ^ poly;
            }
            else {
                crc <<= 1;
            }
            ch <<= 1;
        }
        crc =  crc &0x0000ffff;
        return crc;
    }

    public static int getccitt16(byte[] data) {
        int ch;
        int crc = 0;

        for (int i = 0; i < data.length; i++) {
            ch = data[i];
            crc = calc_crc(crc,ch);
        }

        return crc;
    }

    public static byte[] chackCRC(String mcuID,byte[] buffer){
        if (buffer!=null )
            try {
                byte[] p = new byte[buffer.length - 2];
                System.arraycopy(buffer, 0, p, 0, buffer.length-2);
                int i = getccitt16(p);
                byte [] tmpLength = new byte[4];
                tmpLength[2] =buffer[buffer.length-2 ];
                tmpLength[3] = buffer[buffer.length-1 ];
                int j = byteArrayToInt(tmpLength);
                if (i == j) {
                    return p;
                }
            }catch (Exception e){
                log.error(e.getMessage());
            }
        log.error("CRC 异常 >>>>> :{}" ,mcuID);
        return null;
    }




    /**
     * byte[]转int
     * @param bytes
     * @return
     */
    public static int byteArrayToInt(byte[] bytes) {
        int value= 0;
        //由高位到低位
        for (int i = 0; i < 4; i++) {
            int shift= (4 - 1 - i) * 8;
            value +=(bytes[i] & 0x000000FF) << shift;//往高位游
        }
        return value;
    }

    public static byte[] toCRCByte(byte[] bytes){

        int crcInt = CRCnew.getccitt16(bytes);

        byte[] datab = new byte[bytes.length+2];
        System.arraycopy(bytes,0,datab,0,datab.length-2);

        byte[] crcByte = CHexConver.intToByteArray(crcInt);

        datab[datab.length-1] = crcByte[2];
        datab[datab.length-2] = crcByte[3];
        return datab;
    }


    public static byte[] toCRCByteV4(byte[] bytes){

        int crcInt = CRCnew.getccitt16(bytes);

        byte[] datab = new byte[bytes.length+2];
        System.arraycopy(bytes,0,datab,0,datab.length-2);

        byte[] crcByte = CHexConver.intToByteArray(crcInt);

        datab[datab.length-1] = crcByte[3];
        datab[datab.length-2] = crcByte[2];
        return datab;
    }
}
